package com.hakim.wfb.customer.service.impl;

import com.hakim.wfb.bean.*;
import com.hakim.wfb.biz.CreditPointBiz;
import com.hakim.wfb.biz.PointOrderBiz;
import com.hakim.wfb.biz.UserBiz;
import com.hakim.wfb.customer.enums.ErrorCodeEnum;
import com.hakim.wfb.customer.params.trans.CalculatePointWithdrawParameter;
import com.hakim.wfb.customer.params.trans.GetWithdrawAddrParameter;
import com.hakim.wfb.customer.params.trans.GetWithdrawRecordParameter;
import com.hakim.wfb.customer.params.trans.WithdrawCreditPointParameter;
import com.hakim.wfb.customer.params.wallet.GetCoinMarketPriceParam;
import com.hakim.wfb.customer.params.wallet.WithdrawWalletParam;
import com.hakim.wfb.customer.result.trans.PointWithdrawCalculateView;
import com.hakim.wfb.customer.result.trans.WithdrawAddrTypeView;
import com.hakim.wfb.customer.result.trans.WithdrawAddrView;
import com.hakim.wfb.customer.result.trans.WithdrawRecordView;
import com.hakim.wfb.customer.result.wallet.CoinMarketPriceResult;
import com.hakim.wfb.customer.result.wallet.WalletWithdrawResult;
import com.hakim.wfb.customer.service.WithdrawService;
import com.hakim.wfb.customer.service.biz.TransPointBizService;
import com.hakim.wfb.customer.service.biz.WithdrawBizService;
import com.hakim.wfb.customer.service.convert.WithdrawAddrDtv;
import com.hakim.wfb.customer.service.convert.WithdrawAddrTypeDtv;
import com.hakim.wfb.customer.service.convert.WithdrawRecordDtv;
import com.hakim.wfb.dao.WithdrawAddrDao;
import com.hakim.wfb.dao.WithdrawAddrTypeDao;
import com.hakim.wfb.dao.WithdrawRecordDao;
import com.hkfs.fundamental.api.data.ListResultEx;
import com.hkfs.fundamental.api.data.ObjectResultEx;
import com.hkfs.fundamental.api.data.ResultEx;
import com.hkfs.fundamental.common.utils.NumberUtils;
import com.hkfs.fundamental.exception.HkfsBizException;
import com.hkfs.fundamental.lock.redis.LockService;
import com.hakim.wfb.common.enums.PointTypeEnum;
import com.hakim.wfb.common.enums.TransTypeEnum;
import com.hakim.wfb.common.enums.WithdrawStatusEnum;
import com.hakim.wfb.common.serial.SerialNoGenerator;
import com.hakim.wfb.common.serial.UUIDGenerator;
import com.hakim.wfb.common.util.DateUtils;
import com.hakim.wfb.common.util.EnumUtils;
import com.hakim.wfb.common.util.LockerUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/7/15.
 */
@Service("withdrawService")
public class WithdrawServiceImpl implements WithdrawService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserBiz userBiz;

    @Autowired
    private WithdrawRecordDao withdrawRecordDao;

    @Autowired
    private WithdrawAddrDao withdrawAddrDao;

    @Autowired
    private WithdrawBizService withdrawBizService;

    @Autowired
    private WithdrawAddrTypeDao withdrawAddrTypeDao;

    @Autowired
    private CreditPointBiz creditPointBiz;

    @Autowired
    private PointOrderBiz pointOrderBiz;

    @Autowired
    private TransPointBizService transPointBizService;

    @Autowired
    private LockService lockService;

    @Override
    @Transactional
    public ResultEx createWithdrawOrder(WithdrawCreditPointParameter param) {

        ResultEx resultEx = new ResultEx();
        if (param.getSessionIdentity() == null ||
                StringUtils.isBlank(param.getSessionIdentity().getUuid())) {
            return resultEx.makeFailedResult();
        }
        Integer lockId = NumberUtils.random(0, 1000000);
        Boolean isLockSuccess = lockService.lock(LockerUtils.UNIQUE_LOCK_Key, LockService.DEFAULT_TRY_LOCK_MILLIS,
                LockService.DEFAULT_AUTO_UNLOCK_MILLIS, lockId);
        if (!isLockSuccess) {
            return resultEx.makeFailedResult("锁定出错！");
        }
        try {
            Date now = new Date();
            String nowStr = DateUtils.dateToStrLong(now) + " ";
            if (param.getWithdrawPoint().compareTo(BigDecimal.ZERO) <= 0) {
                logger.warn(nowStr + "提现额度错误");
                resultEx.setRetCode(ErrorCodeEnum.CREDIT_POINT_INVALID_ERROR.getCode());
                resultEx.setRetMsg(ErrorCodeEnum.CREDIT_POINT_INVALID_ERROR.getMessage());
                return resultEx.makeFailedResult();
            }
            //判断
            String userId = param.getSessionIdentity().getUuid();
            User user = userBiz.getUser(userId);
            if (user == null) {
                logger.warn(nowStr + "用户id：" + userId + ",无此用户信息");
                resultEx.setRetCode(ErrorCodeEnum.USER_NOT_EXIST_ERROR.getCode());
                resultEx.setRetMsg(ErrorCodeEnum.USER_NOT_EXIST_ERROR.getMessage());
                return resultEx.makeFailedResult();
            }
            if (!param.getPayPwd().equals(user.getUserTradePwd())) {
                logger.warn(nowStr + "用户id：" + userId + ",支付密码错误");
                resultEx.setRetCode(ErrorCodeEnum.USER_TRADE_PASSWORD_ERROR.getCode());
                resultEx.setRetMsg(ErrorCodeEnum.USER_TRADE_PASSWORD_ERROR.getMessage());
                return resultEx.makeFailedResult();
            }
            CreditPoint creditPoint = creditPointBiz.getCreditPointById(userId);
            if (creditPoint == null) {
                logger.warn(nowStr + "用户id：" + userId + ",无此用户积分信息");
                resultEx.setRetCode(ErrorCodeEnum.USER_CREDIT_POINT_NOT_EXIST_ERROR.getCode());
                resultEx.setRetMsg(ErrorCodeEnum.USER_CREDIT_POINT_NOT_EXIST_ERROR.getMessage());
                return resultEx.makeFailedResult();
            }
            //提现判断
            //2017-08-28 复投积分暂不支持积分提取
            if (param.getPointType() == PointTypeEnum.ORIGINAL_POINT.getValue() ||
//                    param.getPointType() == PointTypeEnum.REPEAT_POINT.getValue() ||
                    param.getPointType() == PointTypeEnum.STATIC_POINT.getValue()) {
                if (param.getWithdrawPoint().doubleValue() % 100 > 0) {
                    return resultEx.makeFailedResult("请提取100倍数的积分");
                }
            } else if (param.getPointType() == PointTypeEnum.DYNAMIC_POINT.getValue()) {
                if (param.getWithdrawPoint().doubleValue() % 100 > 0 || param.getWithdrawPoint().doubleValue() < 500) {
                    return resultEx.makeFailedResult("请提取500以上，100倍数的积分");
                }
            } else {
                resultEx.setRetCode(ErrorCodeEnum.CREDIT_POINT_TYPE_NOT_SUPPORT_WITHDRAW.getCode());
                resultEx.setRetMsg(ErrorCodeEnum.CREDIT_POINT_TYPE_NOT_SUPPORT_WITHDRAW.getMessage());
                return resultEx.makeFailedResult();
            }
            //提现地址
            WithdrawAddr t = new WithdrawAddr();
            t.setWrUser(user.getTid());
            t.setWrType(param.getAddressType());
            WithdrawAddr withdrawAddr = withdrawAddrDao.get(t);
            if (withdrawAddr == null) {
                return resultEx.makeFailedResult("没有绑定" + param.getAddressType() + "账户！");
            }
            Class<PointTypeEnum> clazz = PointTypeEnum.class;
            String des = (String) EnumUtils.getEnumDescriotionByValue(param.getPointType(), clazz);
            //提现交易流水号
            String orderNo = SerialNoGenerator.getWithdrawalOrderNo(user.getUserPhone());
            //计算兑换后的积分
            CalculatePointWithdrawParameter calculateParameter = new CalculatePointWithdrawParameter();
            calculateParameter.setPointType(param.getPointType());
            calculateParameter.setPointAmount(param.getWithdrawPoint());
            ObjectResultEx<PointWithdrawCalculateView> pointExchangeViewResult = withdrawBizService.calculateWithdrawPoint(calculateParameter);
            if (pointExchangeViewResult.isFailed()) {
                resultEx.setRetCode(pointExchangeViewResult.getRetCode());
                resultEx.setRetMsg(pointExchangeViewResult.getRetMsg());
                return resultEx.makeFailedResult();
            }
            PointWithdrawCalculateView pointWithdrawCalculateView = pointExchangeViewResult.getDataObject();
            if (pointWithdrawCalculateView == null) {
                return resultEx.makeFailedResult("积分提现异常");
            }

            GetCoinMarketPriceParam getCoinMarketPriceParam = new GetCoinMarketPriceParam();
            ObjectResultEx<CoinMarketPriceResult> marketPriceResultObjectResultEx = transPointBizService
                    .getCoinCurrentPrice(getCoinMarketPriceParam);

            if (marketPriceResultObjectResultEx.isFailed()) {
                resultEx.setRetCode(marketPriceResultObjectResultEx.getRetCode());
                resultEx.setRetMsg(marketPriceResultObjectResultEx.getRetMsg());
                return resultEx.makeFailedResult();
            }
            CoinMarketPriceResult coinMarketPriceResult = marketPriceResultObjectResultEx.getDataObject();
            if (coinMarketPriceResult == null) {
                return resultEx.makeFailedResult("积分提现异常,无法获取久福币价格");
            }
            if (param.getCoinPrice().compareTo(coinMarketPriceResult.getCurrentPrice()) != 0) {
                return resultEx.makeFailedResult("积分提现异常,久福币价格错误");
            }
            //实际能提取到交易网的数量
            BigDecimal factWithdraw = pointWithdrawCalculateView.getWithdrawablePointAmount();
            //复消积分
            BigDecimal reusablePoint = pointWithdrawCalculateView.getPointReusable();
            //手续费
            BigDecimal fee = pointWithdrawCalculateView.getPointFee();
            //公益基金
            BigDecimal foundation = pointWithdrawCalculateView.getPointFoundation();
            //相应积分类型减少
            if (param.getPointType() == PointTypeEnum.ORIGINAL_POINT.getValue()) {
                //原始积分提现
                if (creditPoint.getCpOriginalPoint() < param.getWithdrawPoint().doubleValue()) {
                    resultEx.setRetCode(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getCode());
                    resultEx.setRetMsg(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getMessage());
                    return resultEx.makeFailedResult();
                }
                creditPoint.setCpOriginalPoint(creditPoint.getCpOriginalPoint() - param.getWithdrawPoint().doubleValue());
            } else if (param.getPointType() == PointTypeEnum.REPEAT_POINT.getValue()) {
                if (creditPoint.getCpRepeatPoint() < param.getWithdrawPoint().doubleValue()) {
                    resultEx.setRetCode(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getCode());
                    resultEx.setRetMsg(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getMessage());
                    return resultEx.makeFailedResult();
                }
                creditPoint.setCpRepeatPoint(creditPoint.getCpRepeatPoint() - param.getWithdrawPoint().doubleValue());
            } else if (param.getPointType() == PointTypeEnum.STATIC_POINT.getValue()) {
                //静态积分提现
                if (creditPoint.getCpAvailableStaticPoint() < param.getWithdrawPoint().doubleValue()) {
                    resultEx.setRetCode(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getCode());
                    resultEx.setRetMsg(ErrorCodeEnum.CREDIT_POINT_BALANCE_NOT_ENOUGH_ERROR.getMessage());
                    return resultEx.makeFailedResult();
                }
                //静态积分可用静态积分减少
                creditPoint.setCpStaticPoint(creditPoint.getCpStaticPoint() - param.getWithdrawPoint().doubleValue());
                creditPoint.setCpAvailableStaticPoint(creditPoint.getCpAvailableStaticPoint() - param.getWithdrawPoint().doubleValue());
            } else if (param.getPointType() == PointTypeEnum.DYNAMIC_POINT.getValue()) {
                if (creditPoint.getCpDynamicPoint() < param.getWithdrawPoint().doubleValue()) {
                    return resultEx.makeFailedResult("积分不足！");
                }
                creditPoint.setCpDynamicPoint(creditPoint.getCpDynamicPoint() - param.getWithdrawPoint().doubleValue());
            }
            if (reusablePoint != null && reusablePoint.compareTo(BigDecimal.ZERO) > 0) {//复消积分增加
                creditPoint.setCpReusablePoint(creditPoint.getCpReusablePoint() + reusablePoint.doubleValue());
            }
            try {

                int updateCount = creditPointBiz.update(creditPoint);
                if (updateCount <= 0) {
                    throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(), ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
                }

                //增加积分变动流水记录 该类积分为负数
                //提现积分减少
                PointOrder reversePointOrder = new PointOrder();
                reversePointOrder.setTid(UUIDGenerator.getUUID());
                if (param.getPointType() == PointTypeEnum.ORIGINAL_POINT.getValue()) {
                    reversePointOrder.setPoAmount(creditPoint.getCpOriginalPoint());
                } else if (param.getPointType() == PointTypeEnum.REPEAT_POINT.getValue()) {
                    reversePointOrder.setPoAmount(creditPoint.getCpRepeatPoint());
                } else if (param.getPointType() == PointTypeEnum.STATIC_POINT.getValue()) {
//                reversePointOrder.setPoAmount(creditPoint.getCpStaticPoint());
                    reversePointOrder.setPoAmount(creditPoint.getCpAvailableStaticPoint());
                } else if (param.getPointType() == PointTypeEnum.DYNAMIC_POINT.getValue()) {
                    reversePointOrder.setPoAmount(creditPoint.getCpDynamicPoint());
                }
                reversePointOrder.setPoCreateDate(DateUtils.getNow());
                reversePointOrder.setPoDescription("提现：" + des + "-" + param.getWithdrawPoint());
                reversePointOrder.setPoFromUser(user.getTid());
                reversePointOrder.setPoOrderno(orderNo);
                reversePointOrder.setPoPointType(param.getPointType());
                reversePointOrder.setPoToUser(user.getTid());
                reversePointOrder.setPoTransPoint(param.getWithdrawPoint().doubleValue() * -1);
                reversePointOrder.setPoType(TransTypeEnum.WITHDRAWAL.getValue());
                pointOrderBiz.add(reversePointOrder);

                logger.info(nowStr + user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，积分变动订单号！【" + orderNo + "】");

                //复消积分增加
                if (reusablePoint != null && reusablePoint.compareTo(BigDecimal.ZERO) > 0) {
                    PointOrder reusablePointOrder = new PointOrder();
                    reusablePointOrder.setTid(UUIDGenerator.getUUID());
                    reusablePointOrder.setPoAmount(creditPoint.getCpReusablePoint());
                    reusablePointOrder.setPoCreateDate(DateUtils.getNow());
                    reusablePointOrder.setPoDescription("提现：" + des + param.getWithdrawPoint() + "，增加：" + reusablePoint);
                    reusablePointOrder.setPoFromUser(user.getTid());
                    reusablePointOrder.setPoOrderno(orderNo);
                    reusablePointOrder.setPoPointType(PointTypeEnum.REUSABLE_POINT.getValue());
                    reusablePointOrder.setPoToUser(user.getTid());
                    reusablePointOrder.setPoTransPoint(reusablePoint.doubleValue());
                    reusablePointOrder.setPoType(TransTypeEnum.WITHDRAWAL.getValue());
                    pointOrderBiz.add(reusablePointOrder);
                    logger.info(nowStr + user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，复消积分增加" + reusablePoint + "。积分变动订单号！【" + orderNo + "】");
                }
                //系统增加手续费
                if (fee != null && fee.compareTo(BigDecimal.ZERO) > 0) {
                    PointOrder feePointOrder = new PointOrder();
                    feePointOrder.setTid(UUIDGenerator.getUUID());
                    feePointOrder.setPoAmount(0);
                    feePointOrder.setPoCreateDate(DateUtils.getNow());
                    feePointOrder.setPoDescription(user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，系统手续费增加" + fee);
                    feePointOrder.setPoFromUser(user.getTid());
                    feePointOrder.setPoOrderno(orderNo);
                    feePointOrder.setPoPointType(PointTypeEnum.FEE_POINT.getValue());
                    feePointOrder.setPoToUser("0");
                    feePointOrder.setPoTransPoint(fee.doubleValue());
                    feePointOrder.setPoType(TransTypeEnum.WITHDRAWAL.getValue());
                    pointOrderBiz.add(feePointOrder);
                    logger.info(nowStr + user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，系统手续费增加" + fee + "。积分变动订单号！【" + orderNo + "】");
                }
                //公益基金系统增加
                if (foundation != null && foundation.compareTo(BigDecimal.ZERO) > 0) {
                    PointOrder foundationPointOrder = new PointOrder();
                    foundationPointOrder.setTid(UUIDGenerator.getUUID());
                    foundationPointOrder.setPoAmount(0);
                    foundationPointOrder.setPoCreateDate(DateUtils.getNow());
                    foundationPointOrder.setPoDescription(user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，系统公益基金增加" + foundation);
                    foundationPointOrder.setPoFromUser(user.getTid());
                    foundationPointOrder.setPoOrderno(orderNo);
                    foundationPointOrder.setPoPointType(PointTypeEnum.FOUNDATION_POINT.getValue());
                    foundationPointOrder.setPoToUser("0");
                    foundationPointOrder.setPoTransPoint(foundation.doubleValue());
                    foundationPointOrder.setPoType(TransTypeEnum.WITHDRAWAL.getValue());
                    pointOrderBiz.add(foundationPointOrder);
                    logger.info(nowStr + user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，系统公益基金增加" + foundation + "。积分变动订单号！【" + orderNo + "】");
                }


                BigDecimal coinAmount = BigDecimal.ZERO;

                if (coinMarketPriceResult.getCurrentPrice().compareTo(BigDecimal.ZERO) > 0) {
//                    coinAmount = factWithdraw.divide(coinMarketPriceResult.getCurrentPrice()).setScale(8,
//                            BigDecimal.ROUND_HALF_DOWN);
////                    divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);
                    coinAmount = pointWithdrawCalculateView.getWithdrawablePointAmount().
                            divide(coinMarketPriceResult.getCurrentPrice(), 8, BigDecimal.ROUND_HALF_UP);
                }
                if (coinAmount.compareTo(BigDecimal.ZERO) > 0) {

                    WithdrawWalletParam withdrawWalletParam = new WithdrawWalletParam();
                    withdrawWalletParam.setAmount(coinAmount);
                    withdrawWalletParam.setAddress(withdrawAddr.getWrAddr());

                    ObjectResultEx<WalletWithdrawResult> withdrawResultObjectResultEx = withdrawBizService
                            .withdrawWallet(withdrawWalletParam);

                    if (withdrawResultObjectResultEx.isFailed()) {
                        return resultEx.makeFailedResult("钱包接口调用失败");
                    }
                    WalletWithdrawResult walletWithdrawResult = withdrawResultObjectResultEx.getDataObject();
                    if (walletWithdrawResult == null) {
                        return resultEx.makeFailedResult("钱包接口调用失败");
                    }
                    WithdrawRecord withdrawRecord = new WithdrawRecord();
                    withdrawRecord.setTid(UUIDGenerator.getUUID());
                    withdrawRecord.setWrUser(user.getTid());
                    withdrawRecord.setWrOrderno(orderNo);
                    withdrawRecord.setWrPointType(param.getPointType());
                    withdrawRecord.setWrPoint(param.getWithdrawPoint());
                    withdrawRecord.setWrActualPoint(factWithdraw);
                    withdrawRecord.setWrReusablePoint(reusablePoint);
                    withdrawRecord.setWrWalfarePoint(foundation);
                    withdrawRecord.setWrChargePoint(fee);
                    withdrawRecord.setWrAddrType(withdrawAddr.getWrType());
                    withdrawRecord.setWrAddr(withdrawAddr.getWrAddr());
                    withdrawRecord.setWrCoinCode(coinMarketPriceResult.getCoinCode());
                    withdrawRecord.setWrCoinPrice(coinMarketPriceResult.getCurrentPrice());
                    withdrawRecord.setWrCoinAmount(coinAmount);
                    withdrawRecord.setWrWithdrawDate(now);
                    withdrawRecord.setWrWithdrawStatus(WithdrawStatusEnum.PROCESSING.getValue());
                    withdrawRecord.setWrTransactionId(walletWithdrawResult.getTxid());
                    withdrawRecordDao.add(withdrawRecord);
                    logger.info(nowStr + user.getUserCode() + "提现：" + des + param.getWithdrawPoint() + "，。提现订单号！【" + orderNo + "】");
                }

                return resultEx.makeSuccessResult();

            } catch (Exception e) {
                e.printStackTrace();
                return resultEx.makeFailedResult("系统错误！");
            }


        } catch (Exception e) {
            resultEx.makeFailedResult();
        } finally {
            if (isLockSuccess) {
                lockService.unlock(LockerUtils.UNIQUE_LOCK_Key, lockId);
            }
        }
        return resultEx;
    }


    @Override
    public ListResultEx<WithdrawRecordView> getWithdrawRecords(GetWithdrawRecordParameter param) {
        ListResultEx<WithdrawRecordView> result = new ListResultEx<>();
        if (param.getSessionIdentity().getUuid().equals("")) {
            return result.makeFailedResult();
        } else if (param.getSessionIdentity() == null || param.getSessionIdentity().getUuid() == null) {
            return result.makeFailedResult();
        }

        List<WithdrawRecordView> listView = new ArrayList<>();
        List<WithdrawRecord> list = withdrawRecordDao.getWithdrawRecords(param);

        //json重整
        for (int i = 0; i < list.size(); i++) {
            listView.add(WithdrawRecordDtv.convert(list.get(i)));
        }
        result.setPageSize(param.getPageSize());
        result.setPageNo(param.getPageNo());
        result.setDataList(listView);
        result.setTotalCount(withdrawRecordDao.getWithdrawRecordCount(param));
        return result.makeSuccessResult();
    }

    @Override
    public ListResultEx<WithdrawAddrView> getWithdrawAddrs(String userId) {
        ListResultEx<WithdrawAddrView> result = new ListResultEx<>();

        if (userId == null || userId.equals(""))
            return result.makeFailedResult();
        try {
            List<WithdrawAddrView> listView = new ArrayList<>();
            List<WithdrawAddr> list = withdrawAddrDao.getWithdrawAddrs(userId);

            //json重整
            for (int i = 0; i < list.size(); i++) {
                listView.add(WithdrawAddrDtv.convert(list.get(i)));
            }
            result.setDataList(listView);
            return result.makeSuccessResult();
        } catch (Exception e) {
            return result.makeFailedResult();
        }
    }

    @Override
    public ResultEx updateAddr(GetWithdrawAddrParameter param) {
        ResultEx resultEx = new ResultEx();
        try {
            WithdrawAddr addr = new WithdrawAddr();
            addr.setWrType(param.getType());
            addr.setWrUser(param.getUserId());

            WithdrawAddr t = withdrawAddrDao.get(addr);
            if (t == null) {
                t = new WithdrawAddr();
                t.setTid(UUIDGenerator.getUUID());
                t.setWrAddr(param.getAddress());
                t.setWrType(param.getType());
                t.setWrUser(param.getUserId());
                withdrawAddrDao.add(t);
            } else {
                if (t.getWrAddr() != param.getAddress()) {
                    t.setWrAddr(param.getAddress());
                    withdrawAddrDao.update(t);
                }
            }
            return resultEx.makeSuccessResult();
        } catch (Exception e) {
            return resultEx.makeFailedResult();
        }
    }

    @Override
    public ListResultEx<WithdrawAddrTypeView> getTypes() {
        ListResultEx<WithdrawAddrTypeView> result = new ListResultEx<>();
        try {
            List<WithdrawAddrTypeView> listView = new ArrayList<>();
            List<WithdrawAddrType> list = withdrawAddrTypeDao.getTypes();

            //json重整
            for (int i = 0; i < list.size(); i++) {
                listView.add(WithdrawAddrTypeDtv.convert(list.get(i)));
            }
            result.setDataList(listView);
            return result.makeSuccessResult();
        } catch (Exception e) {
            return result.makeFailedResult();
        }
    }

    /**
     * 计算积分提现
     *
     * @param param
     * @return
     */
    @Override
    public ObjectResultEx<PointWithdrawCalculateView> calculateWithdrawPoint(CalculatePointWithdrawParameter param) {

        ObjectResultEx<PointWithdrawCalculateView> resultEx = new ObjectResultEx();
        ObjectResultEx<PointWithdrawCalculateView> pointExchangeViewResult = withdrawBizService.calculateWithdrawPoint(param);
        if (pointExchangeViewResult.isFailed()) {
            resultEx.setRetCode(pointExchangeViewResult.getRetCode());
            resultEx.setRetMsg(pointExchangeViewResult.getRetMsg());
            return resultEx.makeFailedResult();
        }
        PointWithdrawCalculateView pointWithdrawCalculateView = pointExchangeViewResult.getDataObject();

        if (pointWithdrawCalculateView == null) {
            return resultEx.makeFailedResult("计算失败");
        }

        GetCoinMarketPriceParam getCoinMarketPriceParam = new GetCoinMarketPriceParam();
        ObjectResultEx<CoinMarketPriceResult> marketPriceResultObjectResultEx = transPointBizService
                .getCoinCurrentPrice(getCoinMarketPriceParam);
        if (marketPriceResultObjectResultEx.isFailed()) {
            resultEx.setRetCode(marketPriceResultObjectResultEx.getRetCode());
            resultEx.setRetMsg(marketPriceResultObjectResultEx.getRetMsg());
            return resultEx.makeFailedResult();
        }
        CoinMarketPriceResult coinMarketPriceResult = marketPriceResultObjectResultEx.getDataObject();
        if (coinMarketPriceResult == null) {
            return resultEx.makeFailedResult("计算异常,无法获取久福币价格");
        }
        //        if (param.getCoinPrice().compareTo(coinMarketPriceResult.getCurrentPrice()) != 0) {
//            return resultEx.makeFailedResult("计算异常,久福币价格错误");
//        }
        BigDecimal coinAmount = BigDecimal.ZERO;

        if (pointWithdrawCalculateView.getWithdrawablePointAmount().compareTo(BigDecimal.ZERO) > 0 &&
                coinMarketPriceResult.getCurrentPrice().compareTo(BigDecimal.ZERO) > 0) {

            coinAmount = pointWithdrawCalculateView.getWithdrawablePointAmount().
                    divide(coinMarketPriceResult.getCurrentPrice(), 8, BigDecimal.ROUND_HALF_UP);
//                    BigDecimal.ROUND_HALF_DOWN);

            if (coinAmount.compareTo(BigDecimal.ZERO) > 0) {

                pointWithdrawCalculateView.setCoinPrice(coinMarketPriceResult.getCurrentPrice());
                pointWithdrawCalculateView.setCoinAmount(coinAmount);

                resultEx.setDataObject(pointWithdrawCalculateView);
                return resultEx.makeSuccessResult();
            }
        }
        return resultEx.makeFailedResult("计算异常");
    }
}
